package com.hehe.service.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hehe.powernode.mapper.SysMenuMapper;
import com.hehe.powernode.pojo.SysMenu;
import com.hehe.service.SysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

//由于管理员用户登录后台管理系统的频率比较高，并且管理员所拥有的权限不会经常的发生变化，
// 所以将每个管理员所拥有的权限存放到redis缓存中，
// 可以提升系统的性能和用户体验，并且减轻数据库服务器的压力。具体内容如下所示：
@CacheConfig(cacheNames = "com.hehe.service.impl.SysMenuServiceImpl")
@Service
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    /**
     * 根据用户ID查询菜单集合
     * @param userId
     * @return
     */
    @Cacheable(value = "userMenuCache", key="#userId")
    @Override
    public List<SysMenu> selectMenuByUserId(Long userId)   {
        // 根据用户ID查询菜单集合
        List<SysMenu> sysMenus = baseMapper.selectMenuByUserId(userId);
        // 判断菜单集合是否有值
        if (!CollectionUtils.isEmpty(sysMenus) && sysMenus.size() != 0) {
            // 将菜单集合转换为树结构
            sysMenus = translateMenusToTree(sysMenus,0L);
        }
        log.info("selectMenuByUserId, sysMenus:{}", sysMenus.size());
        return sysMenus;
    }
    /**
     * 将菜单集合转换为树结构
     * @param sysMenus
     * @param pid
     * @return
     */
    private List<SysMenu> translateMenusToTree(List<SysMenu> sysMenus, Long pid) {
        // 获取菜单的根节点集合
        List<SysMenu> roots = sysMenus.stream()
                .filter(menu -> menu.getParentId().equals(pid))
                .collect(Collectors.toList());
        // 循环遍历父节点集合，根据指定父节点id查询子节点集合
        roots.forEach(r -> r.setList(translateMenusToTree(sysMenus,r.getMenuId())));
        return roots;
    }

}
